#include    "../core/scheduler.h"

extern "C" {
#include	<luajit.h>
#include	<lualib.h>
#include	<lauxlib.h>
}

namespace {
    int Timer(lua_State * lua) {
        double delay = (double)lua_tonumber(lua, 1);
        lua_pushvalue(lua, 2);
        int proc = luaL_ref(lua, LUA_REGISTRYINDEX);
        bool loop = lua_gettop(lua) > 2 ? lua_toboolean(lua, 3) : false;
        uint64_t id = Scheduler::Instance().Add(delay, proc, loop);
        lua_pushinteger(lua, (lua_Integer)id);
        return 1;
    }

    int Daily(lua_State * lua) {
        int hour = (int)lua_tointeger(lua, 1);
        int minute = (int)lua_tointeger(lua, 2);
        int second = (int)lua_tointeger(lua, 3);
        lua_pushvalue(lua, 4);
        int proc = luaL_ref(lua, LUA_REGISTRYINDEX);
        uint64_t id = Scheduler::Instance().Add(hour, minute, second, proc);
        lua_pushinteger(lua, (lua_Integer)id);
        return 1;
    }

    int IsValid(lua_State * lua) {
        bool valid = Scheduler::Instance().IsValid((int)(lua_tointeger(lua, 1)));
        lua_pushboolean(lua, valid ? 1 : 0);
        return 1;
    }

    int RemainTime(lua_State * lua) {
        double left = Scheduler::Instance().GetRemainTime((int)lua_tointeger(lua, 1));
        lua_pushnumber(lua, (lua_Number)left);
        return 1;
    }

    int Cancel(lua_State * lua) {
        Scheduler::Instance().Cancel((int)lua_tointeger(lua, 1));
        return 0;
    }
}

void RegisterApi_Scheduler(lua_State * lua) {
    lua_newtable(lua);

	lua_pushcfunction(lua, &Timer);
	lua_setfield(lua, -2, "timer");

	lua_pushcfunction(lua, &Daily);
	lua_setfield(lua, -2, "daily");
    
	lua_pushcfunction(lua, &IsValid);
	lua_setfield(lua, -2, "is_valid");
    
	lua_pushcfunction(lua, &RemainTime);
	lua_setfield(lua, -2, "remain");

	lua_pushcfunction(lua, &Cancel);
	lua_setfield(lua, -2, "cancel");

	lua_setglobal(lua, "scheduler");
}